#include <iostream>
#include <atomic>
#include <mutex>
#include <queue>
using namespace std;

class PV
{
private:
    atomic_short signal;
    queue<mutex*> allMutex;
    mutex queueLock;

public:
    PV(short signal) : signal(signal) {}

    void P()
    {
        if(signal>0)
            signal--;
        else
        {
            signal=0;
            mutex myMutex;
            //向allMutex添加myMutex
            queueLock.lock();
            allMutex.push(&myMutex);
            queueLock.unlock();
            //完成
            myMutex.lock(); //等别人解锁
        }
    }

    void V()
    {
        if(signal>0)
            signal++;
        else
        {
            //从队列中取出待解锁线程
            queueLock.lock();
            if(!allMutex.empty())
            {
                mutex* aMutex=allMutex.front();
                allMutex.pop();
                aMutex->unlock(); //解锁线程
            }
            else
            {
                signal++;
            }
            queueLock.unlock();
        }
    }
};

PV* pv;

void tfun(int num)
{
    pv->P();
    cout<<num<<"ok"<<endl;
    pv->V();
}

int main()
{
    pv=new PV(2);
    std::thread t1(tfun,1);
    t1.join();
    std::thread t2(tfun,2);
    t2.join();
    std::thread t3(tfun,3);
    t3.join();
}
